<template>
	<div>
		<div>
			<scroll-view
				:scroll-x="true"
				ref="scrollView"
				id="scrollView"
				:scroll-with-animation="true"
				:scroll-left="scrollLeft">
				<div class="box">
					<div
						class="item"
						v-for="(item, index) in dict.list"
						:id="[value === getDictValue(item) ? 'actived' : '']"
						@click="handlerClick(item, index)">
						<span class="label">
							{{ getDictLabel(item) }}
						</span>
						<div
							class="bg"
							v-if="value === getDictValue(item)"
							:style="{ width: width + '%' }"></div>
					</div>
				</div>
			</scroll-view>
		</div>
	</div>
</template>

<script>
	export default {
		name: '',
		components: {},
		props: {
			value: {
				required: false,
			},
			dict: {
				type: Object,
				default() {
					return {
						list: [],
					};
				},
			},
		},
		data() {
			return {
				query: null,
				vnode: {
					scrollView: null,
				},
				safeRight: 100,
				scrollLeft: 0,
				width: 0,
				defaultWidth: 0,
				fitWidth: 100,
			};
		},
		computed: {},
		created() {},
		mounted() {
			this.getSrollViewInfo();
			if (this.Empty(this.value)) {
				this.$emit('input', this.getDictValue(this.dict.list?.[0]));
			} else {
				this.showBorder();
			}
		},
		methods: {
			getSrollViewInfo() {
				let query = uni.createSelectorQuery().in(this);
				query
					.select('#scrollView')
					.boundingClientRect(data => {
						this.vnode.scrollView = data;
					})
					.exec();
			},
			getDictValue(item) {
				return item?.value ?? item?.dictValue ?? item[this.dict.value];
			},
			getDictLabel(item) {
				return item?.label ?? item?.dictLabel ?? item[this.dict.label];
			},
			handlerClick(item) {
				let newValue = this.getDictValue(item);
				let index = this.dict.list.findIndex(
					e => this.getDictValue(e) == newValue,
				);
				if (this.value !== newValue) {
					this.$emit('change', { value: newValue, index: index });
				}
				this.width = this.defaultWidth;
				let query = uni.createSelectorQuery().in(this);
				query
					.selectAll('.item')
					.boundingClientRect(data => {
						let el = data[index];

						let prevEl = data[index - 1] ?? {};
						let nextEl = data[index + 1] ?? {};
						let scrollLeft = 0;
						for (let i = 0; i < index; i++) {
							const element = data[index];
							scrollLeft += element.width;
						}
						if (!el || !this.vnode.scrollView) return;
						let scrollView = this.vnode.scrollView;

						if (
							el.width +
								el.left +
								(nextEl.width ?? this.safeRight) >=
							scrollView.width
						) {
							this.scrollLeft =
								scrollLeft +
								el.width +
								(nextEl.width ?? this.safeRight) -
								scrollView.width;
						}
						if (el.left <= 0) {
							this.scrollLeft =
								scrollLeft - (prevEl?.width ?? this.safeRight);
						}

						this.$emit('input', newValue);
						this.showBorder();
					})
					.exec();
			},
			showBorder() {
				this.$nextTick(() => {
					this.width = this.fitWidth;
				});
			},
		},
	};
</script>

<style lang="scss" scoped>
	.box {
		width: fit-content;
		display: flex;
		margin: 0 15px;
		.item {
			justify-content: space-around;
			padding: 15rpx 25rpx;
			text-align: center;
			position: relative;
			word-break: keep-all;
			.label {
				min-width: 100px;
			}
			.bg {
				position: absolute;
				transition: width 0.5s;
				transform-origin: center;
				background-color: #69a1fa;
				height: 5px;
				position: absolute;
				left: 50%;
				bottom: 0px;
				transform: translateX(-50%);
				will-change: auto;
			}
		}
	}
</style>
